package top.zywork.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.zywork.common.TransactionNoGenerator;
import top.zywork.dao.UserUserSocialDAO;
import top.zywork.dao.UserWithdrawDAO;
import top.zywork.dos.UserUserSocialDO;
import top.zywork.dos.UserWithdrawDO;
import top.zywork.enums.*;
import top.zywork.query.UserUserSocialQuery;
import top.zywork.service.PayService;
import top.zywork.service.UserWithdrawService;
import top.zywork.vo.ResponseStatusVO;

import java.math.BigDecimal;
import java.util.List;

/**
 * 用户提现Service实现类<br/>
 *
 * 创建于2018-12-23<br/>
 *
 * @author 王振宇
 * @version 1.0
 */
@Service
public class UserWithdrawServiceImpl implements UserWithdrawService {

    private UserWithdrawDAO userWithdrawDAO;

    private PayService payService;

    private UserUserSocialDAO userUserSocialDAO;

    @Override
    public int saveWithdraw(Long userId, Byte withdrawType, Byte withdrawClientApp, BigDecimal amount, Long bankcardId) {
        return userWithdrawDAO.saveWithdraw(userId, TransactionNoGenerator.generateNo(), withdrawType, withdrawClientApp, amount, bankcardId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int checkWithdraw(Long userId, Long withdrawId, String transactionNo, Byte withdrawStatus, String description, Long checkedUserId, Integer newVersion) {
        int updatedRows = userWithdrawDAO.updateWithdrawCheck(userId, transactionNo, withdrawStatus, description, checkedUserId, newVersion);
        if (updatedRows == 1) {
            userWithdrawDAO.saveWithdrawCheck(withdrawId, transactionNo, withdrawStatus, description, checkedUserId);
        }
        return updatedRows;
    }

    @Override
    public int cancelWithdraw(String transactionNo, Integer newVersion) {
        return userWithdrawDAO.updateWithdraw(transactionNo, WithdrawStatusEnum.CANCELED.getValue().byteValue(), "用户取消提现", newVersion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeWithdraw(Long withdrawId, String transactionNo, Byte withdrawStatus, Long userId, BigDecimal amount,
                                Long completeUserId, Integer newVersion, Byte withdrawType, Byte withdrawClientApp) {
        if (withdrawStatus == WithdrawStatusEnum.SUCCESS.getValue().byteValue()) {
            int totalAmount = amount.multiply(new BigDecimal(100)).intValue();
            ResponseStatusVO responseStatusVO = null;
            if (withdrawType == WithdrawTypeEnum.BANKCARD.getValue().byteValue()) {
                responseStatusVO = payService.withdrawToBankcardHuman(userId, transactionNo, totalAmount, "人工提现到银行卡");
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN.getValue().byteValue() && withdrawClientApp == ClientAppEnum.WEIXIN_GZH.getValue().byteValue()) {
                responseStatusVO = payService.withdrawToPersonalGzh(userId, getOpenid(userId, withdrawClientApp), "127.0.0.1", transactionNo, totalAmount,
                        "NO_CHECK", "用户提现", "微信公众号提现到微信钱包");
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN.getValue().byteValue() && withdrawClientApp == ClientAppEnum.WEIXIN_XCX.getValue().byteValue()) {
                responseStatusVO = payService.withdrawToPersonalXcx(userId, getOpenid(userId, withdrawClientApp), "127.0.0.1", transactionNo, totalAmount,
                        "NO_CHECK", "用户提现", "微信小程序提现到微信钱包");
            }
            if (responseStatusVO == null || responseStatusVO.getCode().intValue() != ResponseStatusEnum.OK.getCode().intValue()) {
                withdrawStatus = WithdrawStatusEnum.FAILURE.getValue().byteValue();
            }
            int updateRows = userWithdrawDAO.updateWithdraw(transactionNo, withdrawStatus,  getWithdrawDescription(withdrawType, withdrawStatus), newVersion);
            return updateRows == 1;
        }
        return false;
    }

    private String getWithdrawDescription(Byte withdrawType, Byte withdrawStatus) {
        String withdrawDescription = null;
        if (withdrawStatus == WithdrawStatusEnum.SUCCESS.getValue().byteValue()) {
            if (withdrawType == WithdrawTypeEnum.BANKCARD.getValue().byteValue()) {
                withdrawDescription = "人工提现到银行卡成功";
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN.getValue().byteValue()) {
                withdrawDescription = "提现到微信钱包成功";
            } else if (withdrawType == WithdrawTypeEnum.ALIPAY.getValue().byteValue()) {
                withdrawDescription = "提现到支付宝钱包成功";
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN_BANKCARD.getValue().byteValue()) {
                withdrawDescription = "微信提现到银行卡成功";
            }
        } else if (withdrawStatus == WithdrawStatusEnum.FAILURE.getValue().byteValue()) {
            if (withdrawType == WithdrawTypeEnum.BANKCARD.getValue().byteValue()) {
                withdrawDescription = "人工提现到银行卡失败";
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN.getValue().byteValue()) {
                withdrawDescription = "提现到微信钱包失败";
            } else if (withdrawType == WithdrawTypeEnum.ALIPAY.getValue().byteValue()) {
                withdrawDescription = "提现到支付宝钱包失败";
            } else if (withdrawType == WithdrawTypeEnum.WEIXIN_BANKCARD.getValue().byteValue()) {
                withdrawDescription = "微信提现到银行卡失败";
            }
        }
        return withdrawDescription;
    }

    @Override
    public BigDecimal getAvailableWithdraw(Long userId) {
        return userWithdrawDAO.getAvailableWithdraw(userId);
    }

    @Override
    public UserWithdrawDO getByTransactionNo(String transactionNo) {
        return userWithdrawDAO.getByTransactionNo(transactionNo);
    }

    /**
     * 根据用户编号和第三方登录方式去获取用户的openid
     * @param userId
     * @param withdrawClientApp
     * @return
     */
    private String getOpenid(Long userId, Byte withdrawClientApp) {
        String openid = null;
        String socialType = null;
        if (withdrawClientApp == ClientAppEnum.WEIXIN_GZH.getValue().byteValue()) {
            socialType = SocialTypeEnum.WEIXIN_GZH.getValue();
        } else if (withdrawClientApp == ClientAppEnum.WEIXIN_XCX.getValue().byteValue()) {
            socialType = SocialTypeEnum.WEIXIN_XCX.getValue();
        }
        if (socialType != null) {
            List<Object> userObjList = userUserSocialDAO.listAllByCondition(UserUserSocialQuery.builder().userId(userId).userSocialSocialType(socialType).build());
            if (userObjList != null && userObjList.size() > 0) {
                openid = ((UserUserSocialDO) userObjList.get(0)).getUserSocialOpenid();
            }
        }
        return openid;
    }

    @Autowired
    public void setUserWithdrawDAO(UserWithdrawDAO userWithdrawDAO) {
        this.userWithdrawDAO = userWithdrawDAO;
    }

    @Autowired
    public void setPayService(PayService payService) {
        this.payService = payService;
    }

    @Autowired
    public void setUserUserSocialDAO(UserUserSocialDAO userUserSocialDAO) {
        this.userUserSocialDAO = userUserSocialDAO;
    }
}
